package com.sinai.mshab.format;

import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * The purpose of the container to to encapsulate a widget and surround it with
 * anything extra it may need, such as labels, validators etc.
 * 
 * @author serge
 * 
 */
public class FormattingContainer extends DockPanel {

	/**
	 * This is where we keep all the defaults of the panel we belong to.
	 */
	private FormatPanelDefaults defaults;

	/**
	 * This is our main widget that we encapsulate.
	 */
	private Widget widget;

	/**
	 * This is a little message box which yells at you if you do not fill in a
	 * required field
	 */
	private NotifyPanel required_notify;

	/**
	 * This is a message which will yell at you if the validation does not pass.
	 */
	private NotifyPanel validation_notify;

	/**
	 * This is the title label associated with the widget.
	 */
	private Label title;

	/**
	 * Creates a new container
	 * 
	 * @param defaults
	 * 
	 * @param w
	 *            the wiget to be contained
	 */
	public FormattingContainer(FormatPanelDefaults def, Widget w) {
		this.defaults = def;
		widget = w;
		add(widget, DockPanel.CENTER);
		setStylePrimaryName("mshab-container");
	}

	/**
	 * Adds a default required field notifier
	 */
	public void addRequiredNotification() {
		addRequiredNotification("This field is required.");
	}

	/**
	 * Adds a custom required field notification.
	 * 
	 * @param message
	 *            the message to display
	 */
	public void addRequiredNotification(String message) {
		required_notify = new NotifyPanel(message);
		required_notify.warningMode();
		required_notify.setVisible(false);
		add(required_notify, DockPanel.SOUTH);
	}

	public void showRequiredNotifier() {
		if (required_notify != null)
			required_notify.setVisible(true);
	}

	public void hideRequiredNotifier() {
		if (required_notify != null)
			required_notify.setVisible(false);
	}

	/**
	 * Adds a validation failed notifier.
	 * 
	 * @param errorMessage
	 */
	public void addValidator(String errorMessage) {
		validation_notify = new NotifyPanel(errorMessage);
		validation_notify.setVisible(false);
		validation_notify.errorMode();
		add(validation_notify, DockPanel.SOUTH);
	}

	/**
	 * This will show the validation notifier regardless of whether or not any
	 * validation succeeded or failed.
	 */
	public void showValidationNotifier() {
		if (validation_notify != null)
			validation_notify.setVisible(true);
	}

	/**
	 * This will hide the validation notifier regardless of whether or not any
	 * validation succeeded or failed.
	 */
	public void hideValidationNotifier() {
		if (validation_notify != null)
			validation_notify.setVisible(false);
	}

	/**
	 * Adds a label to the default label position.
	 * 
	 * @param message
	 *            the message to appear in the label.
	 */
	public void setLabel(String title) {
		addLabel(title, defaults.getLabelPosition());
	}

	/**
	 * Adds a label to either top or right of the widget.
	 * 
	 * @param message
	 *            the message to appear in the label.
	 * @param dir
	 *            the direction of the label.
	 */
	public void addLabel(String message, Direction dir) {

		// if the label already exists, replace it.
		if (title != null) {
			title.setText(message);
		} else {
			// set up the label
			title = new Label(message);

			// figure out the direction based on user input
			DockLayoutConstant direction = getDirection(dir);
			if (direction != DockPanel.WEST && direction != DockPanel.NORTH) {
				throw new IllegalStateException(
						"Use LEFT or TOP directions for labels only.");
			}

			// set width - only if it's a left label.
			if (dir == Direction.LEFT) {
				title.setWidth(defaults.getLeftLabelWidth() + "px");
			}

			// finally add it.
			add(title, direction);
		}
	}

	/**
	 * Adds a widget to either TOP, LEFT, or RIGHT of the widget.
	 * 
	 * @param header
	 *            the widget to be added
	 * @param dir
	 *            the direction of the header widget
	 */
	public void addWidget(Widget header, Direction dir) {
		// figure out the position
		DockLayoutConstant direction = getDirection(dir);

		// add the widget in.
		add(header, direction);
	}

	/**
	 * Returns a dockPanel direction given a mshab-direction
	 * 
	 * @param dir
	 *            mshab-direction
	 * @return dockpanel equivalent direction.
	 */
	private DockLayoutConstant getDirection(Direction dir) {
		DockLayoutConstant direction = null;
		if (dir == Direction.LEFT) {
			direction = DockPanel.WEST;
		} else if (dir == Direction.TOP) {
			direction = DockPanel.NORTH;
		} else if (dir == Direction.RIGHT) {
			direction = DockPanel.EAST;
		} else if (dir == Direction.BOTTOM) {
			direction = DockPanel.SOUTH;
		}
		return direction;
	}

}
